package cn.topcode.unicorn.wxsdk.user;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.topcode.unicorn.utils.http.HttpUtil;
import cn.topcode.unicorn.wxsdk.WXContext;
import cn.topcode.unicorn.wxsdk.base.ApiUrl;
import cn.topcode.unicorn.wxsdk.base.Result;
import cn.topcode.unicorn.wxsdk.user.dto.CreateUserTagResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetBlackListResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetTagListResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetTagUserListResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetUserInfoResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetUserListResult;
import cn.topcode.unicorn.wxsdk.user.dto.GetUserTagResult;
import cn.topcode.unicorn.wxsdk.user.dto.ReqBatchTag;
import cn.topcode.unicorn.wxsdk.user.dto.ReqCreateTag;
import cn.topcode.unicorn.wxsdk.user.dto.ReqDeleteTag;
import cn.topcode.unicorn.wxsdk.user.dto.ReqEditTag;
import cn.topcode.unicorn.wxsdk.user.dto.ReqGetTagUserList;
import cn.topcode.unicorn.wxsdk.user.dto.Tag;

public class UserInvokerImpl implements UserInvoker {

    @Override
    public GetUserListResult getUserList(String mpId, String nextOpenId) {
        if(nextOpenId == null) {
            nextOpenId = "";
        }
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_USER_LIST, token, nextOpenId);
        return HttpUtil.getJson(url, GetUserListResult.class);
    }

    @Override
    public GetUserListResult getUserList(String nextOpenId) {
        return getUserList(WXContext.getDefaultMpId(), nextOpenId);
    }

    @Override
    public Result setRemark(String mpId, String openId, String remark) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.SET_REMARK, token);
        Map<String,String> params = new HashMap<>();
        params.put("remark", remark);
        return HttpUtil.post(url, params, Result.class);
    }

    @Override
    public Result setRemark(String openId, String remark) {
        return setRemark(WXContext.getDefaultMpId(), openId, remark);
    }

    @Override
    public GetUserInfoResult getUserInfo(String mpId, String openId, String language) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_USER_INFO, token, openId, language);
        return HttpUtil.getJson(url, GetUserInfoResult.class);
    }

    @Override
    public GetUserInfoResult getUserInfo(String openId, String language) {
        return getUserInfo(WXContext.getDefaultMpId(), openId, language);
    }

    @Override
    public GetBlackListResult getBlackList(String mpId, String beginOpenId) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_BLACK_LIST, token);
        Map<String,Object> map = new HashMap<>();
        map.put("begin_openid", beginOpenId);
        return HttpUtil.post(map, GetBlackListResult.class, url);
    }

    @Override
    public GetBlackListResult getBlackList(String beginOpenId) {
        return getBlackList(WXContext.getDefaultMpId(), beginOpenId);
    }

    @Override
    public Result markBlack(String mpId, List<String> openIds) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.MARK_BLACK, token);
        Map<String,Object> map = new HashMap<>();
        map.put("opened_list", openIds);
        return HttpUtil.post(map, Result.class, url);
    }

    @Override
    public Result markBlack(List<String> openIds) {
        return markBlack(WXContext.getDefaultMpId(), openIds);
    }

    @Override
    public Result markWhite(String mpId, List<String> openIds) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.MARK_WHITE, token);
        Map<String,Object> map = new HashMap<>();
        map.put("opened_list", openIds);
        return HttpUtil.post(map, Result.class, url);
    }

    @Override
    public Result markWhite(List<String> openIds) {
        return markWhite(WXContext.getDefaultMpId(), openIds);
    }

    @Override
    public CreateUserTagResult createUserTag(String mpId, String name) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.CRREATE_USER_TAG, token);
        ReqCreateTag req = new ReqCreateTag();
        Tag tag = new Tag();
        tag.setName(name);
        req.setTag(tag);
        return HttpUtil.post(req, CreateUserTagResult.class, url);
    }

    @Override
    public CreateUserTagResult createUserTag(String tagName) {
        return createUserTag(WXContext.getDefaultMpId(), tagName);
    }

    @Override
    public GetTagListResult getTagList(String mpId) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_TAG_LIST, token);
        return HttpUtil.getJson(url, GetTagListResult.class);
    }

    @Override
    public GetTagListResult getTagList() {
        return getTagList(WXContext.getDefaultMpId());
    }

    @Override
    public Result editTag(String mpId, Long id, String name) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.EDIT_TAG, token);
        ReqEditTag req = new ReqEditTag();
        Tag tag = new Tag();
        tag.setId(id);
        tag.setName(name);
        req.setTag(tag);
        return HttpUtil.post(req, Result.class, url);
    }

    @Override
    public Result editTag(Long tagId, String tagName) {
        return editTag(WXContext.getDefaultMpId(), tagId, tagName);
    }

    @Override
    public Result deleteTag(String mpId, Long id) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.DELETE_TAG, token);
        ReqDeleteTag req = new ReqDeleteTag();
        Tag tag = new Tag();
        tag.setId(id);
        req.setTag(tag);
        return HttpUtil.post(req, Result.class, url);
    }

    @Override
    public Result deleteTag(Long tagId) {
        return deleteTag(WXContext.getDefaultMpId(), tagId);
    }

    @Override
    public GetTagUserListResult getTagUserList(String mpId, Long tagId, String nextOpenId) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_TAG_USER_LIST, token);
        ReqGetTagUserList req = new ReqGetTagUserList();
        req.setTagid(tagId);
        req.setNextOpenid(nextOpenId);
        return HttpUtil.getJson(url, GetTagUserListResult.class);
    }

    @Override
    public GetTagUserListResult getTagUserList(Long tagId, String nextOpenId) {
        return getTagUserList(WXContext.getDefaultMpId(), tagId, nextOpenId);
    }

    @Override
    public Result batchTag(String mpId, Long tagId, List<String> openIds) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.BATCH_TAG, token);
        ReqBatchTag req = new ReqBatchTag();
        req.setOpenidList(openIds);
        req.setTagid(tagId);
        return HttpUtil.post(req, Result.class, url);
    }

    @Override
    public Result batchTag(Long tagId, List<String> openIds) {
        return batchTag(WXContext.getDefaultMpId(), tagId, openIds);
    }

    @Override
    public Result batchCancelTag(String mpId, Long tagId, List<String> openIds) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.BATCH_CANCEL_TAG, token);
        ReqBatchTag req = new ReqBatchTag();
        req.setOpenidList(openIds);
        req.setTagid(tagId);
        return HttpUtil.post(req, Result.class, url);
    }

    @Override
    public Result batchCancelTag(Long tagId, List<String> openIds) {
        return batchCancelTag(WXContext.getDefaultMpId(), tagId, openIds);
    }

    /**
     * 批量打标签，没有50个openid的限制
     * @param tagId
     * @param openIds
     * @return
     */
    @Override
    public String batchTagUnlimit(String mpId, Long tagId, List<String> openIds) {
        int count = (int) (Math.ceil(openIds.size() * 1.0 / 50));
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i < count ; i ++ ) {
            if(i == count - 1) {
                Result result = this.batchTag(mpId, tagId, openIds.subList(count * 50, openIds.size() - 1));
                sb.append(result.getErrcode() + ":" + result.getErrmsg());
            }else {
                Result result = this.batchTag(mpId, tagId, openIds.subList(count * 50, (count + 1) * 50));
                sb.append(result.getErrcode() + ":" + result.getErrmsg() + ";");
            }
        }
        return sb.toString();
    }

    @Override
    public String batchTagUnlimit(Long tagId, List<String> openIds) {
        return batchTagUnlimit(WXContext.getDefaultMpId(), tagId, openIds);
    }

    /**
     * 批量取消标签，没有50个openid的限制
     * @param tagId
     * @param openIds
     * @return
     */
    @Override
    public String batchCancelTagUnlimit(String mpId, Long tagId, List<String> openIds) {
        int count = (int) (Math.ceil(openIds.size() * 1.0 / 50));
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i < count ; i ++ ) {
            if(i == count - 1) {
                Result result = this.batchCancelTag(mpId, tagId, openIds.subList(count * 50, openIds.size() - 1));
                sb.append(result.getErrcode() + ":" + result.getErrmsg());
            }else {
                Result result = this.batchCancelTag(mpId, tagId, openIds.subList(count * 50, (count + 1) * 50));
                sb.append(result.getErrcode() + ":" + result.getErrmsg() + ";");
            }
        }
        return sb.toString();
    }

    @Override
    public String batchCancelTagUnlimit(Long tagId, List<String> openIds) {
        return batchCancelTagUnlimit(WXContext.getDefaultMpId(), tagId, openIds);
    }

    @Override
    public GetUserTagResult getUserTag(String mpId, String openId) {
        String token = WXContext.getToken(mpId);
        String url = String.format(ApiUrl.User.GET_USER_TAG, token);
        Map<String,Object> map = new HashMap<>();
        map.put("openid", openId);
        return HttpUtil.post(map, GetUserTagResult.class, url);
    }

    @Override
    public GetUserTagResult getUserTag(String openId) {
        return getUserTag(WXContext.getDefaultMpId(), openId);
    }

}
